/**
 * Copyright (c) 2011 eelpo.com
 * All rights reserved.
 */
package com.eelpo.cmmp.core.wicket.component.label;

import com.eelpo.cmmp.core.wicket.behavior.ComponentVisualErrorBehavior;
import com.eelpo.common.util.BlankUtils;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

/**
 * <pre>
 * 
 * 错误信息显示标签
 * 
 * </pre>
 * 
 * @author <a href="mailto:Brian@eelpo.com">汪洪州</a>
 * @since 1.0
 */
public class FeedbackLabel extends Label {

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 6487925886157162517L;

	/**
	 * 是否有变更
	 */
	protected boolean changed;

	/**
	 * 是否检查过变更
	 */
	protected boolean check;

	/**
	 * 错误信息
	 */
	protected IModel<String> text;

	/**
	 * 默认的数据模型
	 */
	protected static IModel<String> defaultModel = new Model<String>("*");

	/**
	 * 目标对象
	 */
	protected FormComponent<?> target;

	public FeedbackLabel(String id, FormComponent<?> target) {
		super(id, defaultModel);

		setOutputMarkupId(true);

		this.target = target;
		this.target.setRequired(true);
		this.target.setOutputMarkupId(true);
		this.target.add(new ComponentVisualErrorBehavior(this));

		this.add(new AttributeModifier("class", true, new Model<String>("feedbacklabel INFO")));
	}

	public FeedbackLabel(String id, FormComponent<?> target, String text) {
		this(id, target, new Model<String>(text));
	}

	public FeedbackLabel(String id, FormComponent<?> target, IModel<String> iModel) {
		super(id, defaultModel);

		this.text = iModel;
		this.target = target;

		setOutputMarkupId(true);

		this.target = target;
		this.target.setRequired(true);
		this.target.setOutputMarkupId(true);
		this.target.add(new ComponentVisualErrorBehavior(this));

		this.add(new AttributeModifier("class", true, new Model<String>("feedbacklabel INFO")));
	}

	public FeedbackLabel(String id, String event, FormComponent<?> target) {
		super(id, defaultModel);

		setOutputMarkupId(true);

		this.target = target;
		this.target.setRequired(true);
		this.target.setOutputMarkupId(true);
		this.target.add(new ComponentVisualErrorBehavior(event, this));

		this.add(new AttributeModifier("class", true, new Model<String>("feedbacklabel INFO")));
	}

	public FeedbackLabel(String id, String event, String text, FormComponent<?> target) {
		this(id, target, new Model<String>(text));
	}

	public FeedbackLabel(String id, String event, IModel<String> iModel, FormComponent<?> target) {
		super(id, defaultModel);

		this.text = iModel;
		this.target = target;

		setOutputMarkupId(true);

		this.target = target;
		this.target.setRequired(true);
		this.target.setOutputMarkupId(true);
		this.target.add(new ComponentVisualErrorBehavior(event, this));

		this.add(new AttributeModifier("class", true, new Model<String>("feedbacklabel INFO")));
	}

	public void valid() {

		setCheck(true);

		if (!BlankUtils.isBlank(target.getFeedbackMessage())) {

			IModel<String> model = BlankUtils.isBlank(text) ? new Model<String>(target.getFeedbackMessage().getMessage().toString()) : text;

			setChanged(!getDefaultModelObjectAsString().equals(model.getObject()));
			if (isChanged()) {
				this.setDefaultModel(model);
				this.add(new AttributeModifier("class", true, new Model<String>("feedbacklabel " + target.getFeedbackMessage().getLevelAsString())));
			}
		} else {

			setChanged(!getDefaultModelObjectAsString().equals(defaultModel.getObject()));
			if (isChanged()) {
				this.setDefaultModel(defaultModel);
				this.add(new AttributeModifier("class", true, new Model<String>("feedbacklabel INFO")));
			}
		}
	}

	@Override
	protected void onBeforeRender() {
		super.onBeforeRender();

		if (!isCheck()) {
			valid();
		}

		setCheck(false);
	}

	public boolean isChanged() {
		return changed;
	}

	public void setChanged(boolean changed) {
		this.changed = changed;
	}

	public boolean isCheck() {
		return check;
	}

	public void setCheck(boolean check) {
		this.check = check;
	}

}
